package com.stars.easyms.monitor.register;

import com.stars.easyms.monitor.MonitorFunc;
import com.stars.easyms.monitor.MonitorRequestHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>className: EasyMsMonitorRegister</p>
 * <p>description: EasyMs监控模块注册类</p>
 *
 * @author guoguifang
 * @version 1.7.0
 * @date 2020/10/28 3:50 下午
 */
public final class EasyMsMonitorRegister {

    private static final Logger logger = LoggerFactory.getLogger(EasyMsMonitorRegister.class);

    private static Set<String> monitorModuleNames;

    private static List<MonitorFunc> monitorFuncList;

    static {
        try {
            Set<MonitorFunc> localMonitorFuncSet = new HashSet<>();

            // 获取所有的实现了MonitorFun接口的类
            ServiceLoader<MonitorFunc> monitorFuncServiceLoader = ServiceLoader.load(MonitorFunc.class);
            for (MonitorFunc monitorFunc : monitorFuncServiceLoader) {
                localMonitorFuncSet.add(monitorFunc);
            }

            // 获取所有的实现了EasyMsMonitorRequestHandler接口的类
            ServiceLoader<MonitorRequestHandler> monitorRequestHandlerServiceLoader = ServiceLoader.load(MonitorRequestHandler.class);
            for (MonitorRequestHandler easyMsMonitorRequestHandler : monitorRequestHandlerServiceLoader) {
                localMonitorFuncSet.add(easyMsMonitorRequestHandler);
            }

            // 排序
            monitorFuncList = localMonitorFuncSet.stream()
                    .sorted(Comparator.comparingInt(MonitorFunc::getOrder))
                    .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));

            // 按照顺序打印扫描到的接口信息
            Set<String> monitorModuleNameSet = new HashSet<>();
            for (MonitorFunc monitorFunc : monitorFuncList) {
                monitorModuleNameSet.add(monitorFunc.getModuleName());
                logger.info("Found {} monitor func: {}, order: {}!", monitorFunc.getModuleName(),
                        monitorFunc.getClass().getCanonicalName(), monitorFunc.getOrder());
            }
            monitorModuleNameSet.add("monitor");
            monitorModuleNames = Collections.unmodifiableSet(monitorModuleNameSet);
        } catch (Exception ex) {
            logger.error("Initialization MonitorFunc failed!", ex);
        }
    }

    public static List<MonitorFunc> getMonitorFuncList() {
        return monitorFuncList;
    }

    public static Set<String> getMonitorModuleNames() {
        return monitorModuleNames;
    }

    private EasyMsMonitorRegister() {}
}
